﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.ComponentModel;
using System.Windows;
using Xceed.Silverlight.ListBox.PositioningFunction;

namespace Xceed.Silverlight.ListBox
{
  public abstract class View : ContainerConfigurationsBase, ISupportInitialize
  {
    #region IsActiveView Property

    public static readonly DependencyProperty IsActiveViewProperty = DependencyProperty.Register(
      "IsActiveView",
      typeof( bool ),
      typeof( View ),
      new PropertyMetadata(
        false,
        new PropertyChangedCallback( View.OnIsActiveViewChanged ) ) );

    public bool IsActiveView
    {
      get
      {
        return ( bool )this.GetValue( View.IsActiveViewProperty );
      }
      set
      {
        this.SetValue( View.IsActiveViewProperty, value );
      }
    }

    private static void OnIsActiveViewChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e )
    {
      View view = sender as View;

      if( view == null )
        return;

      if( view.IsInitializing )
        return;

      view.RaiseIsActiveViewChanged();
    }

    private void RaiseIsActiveViewChanged()
    {
      if( this.IsActiveViewChanged != null )
        this.IsActiveViewChanged( this, EventArgs.Empty );
    }

    internal event EventHandler IsActiveViewChanged;

    #endregion

    internal virtual IScalingFunction GetScalingFunction()
    {
      return null;
    }

    internal virtual IOpacityFunction GetOpacityFunction()
    {
      return null;
    }

    internal virtual IZIndexFunction GetZIndexFunction()
    {
      return null;
    }

    #region PositioningFunction Internal Property

    internal PositioningFunctionBase PositioningFunction
    {
      get
      {
        return m_positioningFunction;
      }
      set
      {
        if( m_positioningFunction != value )
        {
          m_positioningFunction = value;

          if( !this.IsInitializing )
            RaisePositioningFunctionChanged();
        }
      }
    }

    internal event EventHandler PositioningFunctionChanged;

    internal void RaisePositioningFunctionChanged()
    {
      if( this.PositioningFunctionChanged != null )
        this.PositioningFunctionChanged( this, EventArgs.Empty );
    }

    #endregion

    #region BringLastItemToStartingPoint Internal Property

    internal virtual bool BringLastItemToStartingPoint
    {
      get
      {
        return false;
      }
    }

    #endregion

    #region ContainerSizeConstraint Internal Property

    internal ContainerLayoutMode PositioningContainerLayoutMode
    {
      get
      {
        return m_positioningContainerLayoutMode;
      }
      set
      {
        if( value != m_positioningContainerLayoutMode )
        {
          if( value == ContainerLayoutMode.Default )
            throw new InvalidOperationException( "An attempt was made to set the View's PositioningContainerLayoutMode to ContainerLayoutMode.Default." );

          m_positioningContainerLayoutMode = value;
        }
      }
    }

    #endregion

    #region AllowStickyHeaders Internal Read-Only Property

    internal virtual bool AllowStickyHeaders
    {
      get
      {
        return true;
      }
    }

    #endregion

    #region internal
    internal virtual double GetConfigurationDistanceUsedForExtent( ListBoxContainerConfigurationBase configuration )
    {
      return configuration.PrepareSize.Height;
    }
    #endregion

    #region Private Fields

    private PositioningFunctionBase m_positioningFunction;
    private ContainerLayoutMode m_positioningContainerLayoutMode = ContainerLayoutMode.Floating;

    #endregion

    #region ISupportInitialize Members

    void ISupportInitialize.BeginInit()
    {
      m_initializingCount++;
      this.BeginInitCore();
    }

    void ISupportInitialize.EndInit()
    {
      m_initializingCount--;

      if( m_initializingCount == 0 )
        this.EndInitCore();
    }

    internal bool IsInitializing
    {
      get
      {
        return ( m_initializingCount > 0 );
      }
    }

    internal virtual void BeginInitCore()
    {
    }

    internal virtual void EndInitCore()
    {
      if( this.IsActiveView )
        this.RaiseIsActiveViewChanged();
    }

    private int m_initializingCount;

    #endregion
  }
}
